package com.cskaoyan.market.shiro;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;


@Configuration
public class ShiroConfiguration {

    //向容器中注册shiroFilter、SecurityManager、Realm、SessionManager
    //    SessionManager sessionManager;

    @Bean
    public SecurityManager securityManager(SessionManager sessionManager, Realm realm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //因为我们在认证、授权、会话管理过程中都需要使用securityManager
        //所以，我们需要将securityManager和sessionManager以及realm（认证、授权）进行关联
        securityManager.setSessionManager(sessionManager);
        securityManager.setRealm(realm);
        return securityManager;
    }

    /**
     * 整合web必须要使用的一个核心组件，因为在web访问过程中，需要针对用户输入的请求地址进行认证或者授权操作。必须得在filter中获取当前请求的资源路径，和我们设置的权限进行比对
     * 比如/user/login------不需要认证
     * 比如/user/info------需要认证
     * 比如/order/list-----需要认证
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){

        ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
        //关于securityManager
        filterFactoryBean.setSecurityManager(securityManager);

        //注意：此处必须是LinkedHashMap，不可以是hashmap，因为需要保障下面配置的顺序
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        //设置一个匹配的权限规则
        filterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return filterFactoryBean;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }
}
